package com.example.as.untils;

import com.example.as.entity.ChatMessage;
import com.example.as.entity.Record;
import com.example.as.Service.RecordService;
import com.google.gson.Gson;

import java.io.*;
import java.net.Socket;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class SocketListener implements Runnable {
    private final Socket socket;
    String account;
    RecordService recordService;    // 聊天记录 服务类
    private static ConcurrentHashMap<String, ObjectOutputStream> socketMap; // 在线名单

    public SocketListener(Socket socket, ConcurrentHashMap<String, ObjectOutputStream> socketMap, RecordService recordService) {
        this.recordService = recordService;
        this.socket = socket;
        SocketListener.socketMap = socketMap;
    }

    @Override
    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while (true) {
                String line;
                while ((line = reader.readLine()) != null) {
                    // 将 chatMessage 对象从 json 字符串中解析出来
                    String json = doString(line);
                    Gson gson = new Gson();
                    ChatMessage chatMessage = gson.fromJson(json, ChatMessage.class);
                    System.out.println("-------------------------------------");
                    System.out.println("Received ChatMessage: " + chatMessage);
                    System.out.println("-------------------------------------");
                    // 握手报文 录入在线名单
                    if (Objects.equals(chatMessage.getMessageType(), "0")) {
                        ConcurrentHashMap<String, ObjectOutputStream> map = SocketManager.getSocketMap();
                        map.put(chatMessage.getSender(), new ObjectOutputStream(socket.getOutputStream()));
                        account = chatMessage.getSender();
                        System.out.println("-------------------------------------");
                        System.out.println("** OnLine User: " + map.size() + " **");
                        System.out.println("-------------------------------------");
                    } else {
                        // 正常消息处理
                        //  转换对象
                        Record record = new Record();
                        record.setMessageType(Integer.parseInt(chatMessage.getMessageType()));
                        record.setMessage(chatMessage.getMessage());
                        record.setSender(chatMessage.getSender());
                        record.setReceiver(chatMessage.getReceiver());
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date date = sdf.parse(chatMessage.getTimeStamp());
                        Timestamp timestamp = new Timestamp(date.getTime());
                        record.setTimeStamp(timestamp);
                        //  添加记录
                        recordService.addRecord(record);
                        // 转发至对象：向 receiver 的信道流进行转发
                        if (socketMap.containsKey(chatMessage.getReceiver())) {
                            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socketMap.get(chatMessage.getReceiver())));
                            writer.write(line);
                            writer.newLine();
                            writer.flush();
                            System.out.println("*由 "+chatMessage.getSender()+" 到 "+chatMessage.getReceiver() + " 的消息已完成转发……*");
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally { // 断连 移除在线名单
            try {
                socket.close();
                socketMap.remove(account);
                System.out.println("---------------------------------------------------------");
                System.out.println("用户-"+account+"已离线，服务器上现有 "+socketMap.size()+" 用户");
                System.out.println("---------------------------------------------------------");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 字符串处理（未知原因会传输多余的前缀 该方法就是用于提取信息体）
     *
     * @param in 待处理字符串
     * @return 处理完毕的字符串 即：消息体
     */
    public String doString(String in) {
        char[] chars = in.toCharArray();
        int i = 0;
        for (i = 0; i < chars.length; i++) {
            if (chars[i] == '{')
                break;
        }
        return in.substring(i);
    }
}
